{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Chapter 2: Figures"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Robert Johansson\n",
    "\n",
    "Source code listings for [Numerical Python - Scientific Computing and Data Science Applications with Numpy, SciPy and Matplotlib](https://www.apress.com/us/book/9781484242452) (ISBN 978-1-484242-45-2)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "%config InlineBackend.figure_format='retina'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "def show_array(shape, sel, filename=None):\n",
    "    \"\"\"Visualize indexing of arrays\"\"\"\n",
    "\n",
    "    data = np.zeros(shape)\n",
    "    exec(\"data[%s] = 1\" % sel)\n",
    "\n",
    "    fig, ax = plt.subplots(1, 1, figsize=shape)\n",
    "\n",
    "    ax.patch.set_facecolor('black')\n",
    "    ax.set_aspect('equal', 'box')\n",
    "    ax.xaxis.set_major_locator(plt.NullLocator())\n",
    "    ax.yaxis.set_major_locator(plt.NullLocator())\n",
    "\n",
    "    size = 0.97\n",
    "    for (m, n), w in np.ndenumerate(data):\n",
    "        color = '#1199ff' if w > 0 else '#eeeeee'\n",
    "        rect = plt.Rectangle([n - size / 2, m - size / 2],\n",
    "                             size, size,\n",
    "                             facecolor=color,\n",
    "                             edgecolor=color)\n",
    "        ax.add_patch(rect)\n",
    "        ax.text(m, n, \"(%d, %d)\" % (n, m), ha='center', va='center', fontsize=12)\n",
    "        \n",
    "    ax.autoscale_view()\n",
    "    ax.invert_yaxis()\n",
    "\n",
    "    if sel == \":, :\":\n",
    "        ax.set_title(\"data\\n\", fontsize=12)\n",
    "    else:\n",
    "        ax.set_title(\"data[%s]\\n\" % sel, fontsize=12)\n",
    "    \n",
    "    #fig.tight_layout()\n",
    "    \n",
    "    if filename:\n",
    "        fig.savefig(filename + \".png\", dpi=200)\n",
    "        fig.savefig(filename + \".svg\")\n",
    "        fig.savefig(filename + \".pdf\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "show_array((4, 4), \":, :\", \"array_indexing_1\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "show_array((4, 4), \"0\", \"array_indexing_2\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "show_array((4, 4), \"1, :\", \"array_indexing_3\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "show_array((4, 4), \":, 2\", \"array_indexing_4\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "show_array((4, 4), \"0:2, 0:2\", \"array_indexing_5\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "show_array((4, 4), \"0:2, 2:4\", \"array_indexing_6\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "show_array((4, 4), \"::2, ::2\", \"array_indexing_7\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "show_array((4, 4), \"1::2, 1::2\", \"array_indexing_8\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "show_array((4, 4), \":,[0,3]\", \"array_indexing_9\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "show_array((4, 4), \"[1,3],[0,3]\", \"array_indexing_10\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "show_array((4, 4), \":,np.array([False, True, True, False])\", \"array_indexing_11\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "show_array((4, 4), \":,np.array([False, True, True, False])\", \"array_indexing_12\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "show_array((4, 4), \"1:3,np.array([False, True, True, False])\", \"array_indexing_12\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Summary"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<table>\n",
    "<tr>\n",
    "<td><img src=\"./array_indexing_1.svg\"></td>\n",
    "<td><img src=\"./array_indexing_2.svg\"></td>\n",
    "<td><img src=\"./array_indexing_3.svg\"></td>\n",
    "<td><img src=\"./array_indexing_4.svg\"></td>\n",
    "</tr>\n",
    "<tr>\n",
    "<td><img src=\"./array_indexing_5.svg\"></td>\n",
    "<td><img src=\"./array_indexing_6.svg\"></td>\n",
    "<td><img src=\"./array_indexing_7.svg\"></td>\n",
    "<td><img src=\"./array_indexing_8.svg\"></td>\n",
    "</tr>\n",
    "<tr>\n",
    "<td><img src=\"./array_indexing_9.svg\"></td>\n",
    "<td><img src=\"./array_indexing_10.svg\"></td>\n",
    "<td><img src=\"./array_indexing_11.svg\"></td>\n",
    "<td><img src=\"./array_indexing_12.svg\"></td>\n",
    "</tr>\n",
    "</table>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Aggregation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "data = np.arange(9).reshape(3,3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "data.sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "data.sum(axis=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "data.sum(axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "def show_array_aggregation(data, axis, filename=None):\n",
    "    \"\"\"Visualize indexing of arrays\"\"\"\n",
    "   \n",
    "    fig, axes = plt.subplots(2, 1, figsize=(4, 8))\n",
    "\n",
    "    \n",
    "    ax = axes[0]\n",
    "    ax.patch.set_facecolor('black')\n",
    "    #ax.set_aspect('equal', 'box')\n",
    "    ax.xaxis.set_major_locator(plt.NullLocator())\n",
    "    ax.yaxis.set_major_locator(plt.NullLocator())\n",
    "\n",
    "    \n",
    "    colors = ['#1199ff', '#ee3311', '#66ff22']\n",
    "    \n",
    "    for (m, n), w in np.ndenumerate(data):\n",
    "        size = 0.97\n",
    "        color = '#1199ff' if w > 0 else '#eeeeee'\n",
    "        color = '#eeeeee'\n",
    "        rect = plt.Rectangle([n - size / 2, m - size / 2],\n",
    "                             size, size,\n",
    "                             facecolor=color,\n",
    "                             edgecolor=color)\n",
    "        ax.add_patch(rect)\n",
    "        if axis is None:\n",
    "            color = '#1199ff'\n",
    "        elif axis == 1:\n",
    "            color = colors[m]\n",
    "        else:\n",
    "            color = colors[n]\n",
    "            \n",
    "        size = 0.8\n",
    "        rect = plt.Rectangle([n - size / 2, m - size / 2],\n",
    "                             size, size,\n",
    "                             facecolor=color,\n",
    "                             edgecolor=color)\n",
    "        ax.add_patch(rect)\n",
    "\n",
    "        ax.text(n, m, \"%d\" % data[m, n], ha='center', va='center', fontsize=12)\n",
    "        \n",
    "    ax.autoscale_view()\n",
    "    ax.invert_yaxis()\n",
    "    ax.set_title(\"data\", fontsize=12)\n",
    "\n",
    "    if False:\n",
    "        ax = axes[1]\n",
    "        ax.set_frame_on(False)\n",
    "        ax.patch.set_facecolor('white')\n",
    "        ax.xaxis.set_major_locator(plt.NullLocator())\n",
    "        ax.yaxis.set_major_locator(plt.NullLocator())\n",
    "        ax.set_xlim(0, 3)\n",
    "        ax.set_ylim(0, 3)\n",
    "\n",
    "        if axis is not None:\n",
    "            ax.text(1.5, 1.5, \"data.sum(axis=%d)\" % axis, ha='center', va='center', fontsize=18)        \n",
    "        else:\n",
    "            ax.text(1.5, 1.5, \"data.sum()\", ha='center', va='center', fontsize=18)        \n",
    "\n",
    "        ax.arrow(0.3, 1.25, 2.1, 0.0, head_width=0.1, head_length=0.2, fc='k', ec='k')\n",
    "\n",
    "    if axis == 0:\n",
    "        adata = data.sum(axis=axis)[:, np.newaxis]\n",
    "    elif axis == 1:\n",
    "        adata = data.sum(axis=axis)[:, np.newaxis]\n",
    "    else:\n",
    "        adata = np.atleast_2d(data.sum(axis=axis))\n",
    "        \n",
    "    ax = axes[1]\n",
    "    ax.set_frame_on(False)\n",
    "    ax.patch.set_facecolor('white')\n",
    "    ax.xaxis.set_major_locator(plt.NullLocator())\n",
    "    ax.yaxis.set_major_locator(plt.NullLocator())\n",
    "    \n",
    "    \n",
    "    colors = ['#1199ff', '#ee3311', '#66ff22']\n",
    "    \n",
    "    for (m, n), w in np.ndenumerate(data):\n",
    "        size = 1.0\n",
    "        color = '#ffffff'\n",
    "        rect = plt.Rectangle([n - size / 2, m - size / 2],\n",
    "                         size, size,\n",
    "                         facecolor=color,\n",
    "                         edgecolor=color)\n",
    "        ax.add_patch(rect)        \n",
    "    \n",
    "    for (m, n), w in np.ndenumerate(adata):\n",
    "\n",
    "        if axis is None:\n",
    "            size = 1.0\n",
    "            color = '#000000'\n",
    "            rect = plt.Rectangle([1+m - size / 2, 0 + n - size / 2],\n",
    "                             size, size,\n",
    "                             facecolor=color,\n",
    "                             edgecolor=color)\n",
    "            ax.add_patch(rect)        \n",
    "            size = 0.97\n",
    "            color = '#eeeeee'\n",
    "\n",
    "            \n",
    "            rect = plt.Rectangle([1+m - size / 2, 0 + n - size / 2],\n",
    "                                 size, size,\n",
    "                                 facecolor=color,\n",
    "                                 edgecolor=color)\n",
    "            ax.add_patch(rect)\n",
    "\n",
    "            \n",
    "            if axis is None:\n",
    "                color = '#1199ff'\n",
    "            elif axis == 1:\n",
    "                color = colors[n]\n",
    "            else:\n",
    "                color = colors[m]\n",
    "\n",
    "            size = 0.8\n",
    "            rect = plt.Rectangle([1+m - size / 2, 0 + n - size / 2],\n",
    "                                 size, size,\n",
    "                                 facecolor=color,\n",
    "                                 edgecolor=color)\n",
    "            ax.add_patch(rect)\n",
    "\n",
    "            \n",
    "            if n == 0:\n",
    "                ax.text(1+m, n+0, \"%d\" % adata[m, n], ha='center', va='center', fontsize=10)\n",
    "\n",
    "            \n",
    "        if axis == 0:\n",
    "            size = 1.0\n",
    "            color = '#000000'\n",
    "            rect = plt.Rectangle([m - size / 2, 0 + n - size / 2],\n",
    "                             size, size,\n",
    "                             facecolor=color,\n",
    "                             edgecolor=color)\n",
    "            ax.add_patch(rect)        \n",
    "            size = 0.97\n",
    "            color = '#eeeeee'\n",
    "\n",
    "            \n",
    "            rect = plt.Rectangle([m - size / 2, 0 + n - size / 2],\n",
    "                                 size, size,\n",
    "                                 facecolor=color,\n",
    "                                 edgecolor=color)\n",
    "            ax.add_patch(rect)\n",
    "\n",
    "            \n",
    "            if axis is None:\n",
    "                color = '#1199ff'\n",
    "            elif axis == 1:\n",
    "                color = colors[n]\n",
    "            else:\n",
    "                color = colors[m]\n",
    "\n",
    "            size = 0.8\n",
    "            rect = plt.Rectangle([m - size / 2, 0 + n - size / 2],\n",
    "                                 size, size,\n",
    "                                 facecolor=color,\n",
    "                                 edgecolor=color)\n",
    "            ax.add_patch(rect)\n",
    "\n",
    "            \n",
    "            if n == 0:\n",
    "                ax.text(m, n+0, \"%d\" % adata[m, n], ha='center', va='center', fontsize=10)\n",
    "\n",
    "        if axis == 1:\n",
    "            size = 1.0\n",
    "            color = '#000000'\n",
    "            rect = plt.Rectangle([0 + m - size / 2, n - size / 2],\n",
    "                             size, size,\n",
    "                             facecolor=color,\n",
    "                             edgecolor=color)\n",
    "            ax.add_patch(rect)        \n",
    "            size = 0.97\n",
    "            color = '#eeeeee'\n",
    "\n",
    "            rect = plt.Rectangle([0 + m - size / 2, n - size / 2],\n",
    "                                 size, size,\n",
    "                                 facecolor=color,\n",
    "                                 edgecolor=color)\n",
    "\n",
    "            ax.add_patch(rect)\n",
    "\n",
    "            if axis is None:\n",
    "                color = '#1199ff'\n",
    "            elif axis == 1:\n",
    "                color = colors[m]\n",
    "            else:\n",
    "                color = colors[m]\n",
    "\n",
    "            size = 0.8\n",
    "            rect = plt.Rectangle([0 + m - size / 2, n - size / 2],\n",
    "                                 size, size,\n",
    "                                 facecolor=color,\n",
    "                                 edgecolor=color)\n",
    "            ax.add_patch(rect)\n",
    "            \n",
    "            if axis == 0 and m == 0:\n",
    "                ax.text(m+0, n, \"%d\" % adata[m, n], ha='center', va='center', fontsize=12)\n",
    "            if axis == 1 and n == 0:\n",
    "                ax.text(m, n+0, \"%d\" % adata[m, n], ha='center', va='center', fontsize=10)\n",
    "\n",
    "    ax.autoscale_view()\n",
    "    ax.invert_yaxis()\n",
    "    if axis is not None:\n",
    "        ax.set_title(\"data.sum(axis=%d)\" % axis, fontsize=12)\n",
    "    else:\n",
    "        ax.set_title(\"data.sum()\", fontsize=12)\n",
    "    \n",
    "    fig.tight_layout()\n",
    "    \n",
    "    if filename:\n",
    "        fig.savefig(filename + \".png\", dpi=200)\n",
    "        fig.savefig(filename + \".svg\")\n",
    "        fig.savefig(filename + \".pdf\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "data = np.arange(1,10).reshape(3,3)\n",
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "show_array_aggregation(data, None, filename=\"array_aggregation_1\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "show_array_aggregation(data, 0, filename=\"array_aggregation_2\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "show_array_aggregation(data, 1, filename=\"array_aggregation_3\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Broadcasting"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "def show_array_broadcasting(a, b, filename=None):\n",
    "    \"\"\"Visualize broadcasting of arrays\"\"\"\n",
    "\n",
    "    c = a + b\n",
    "    \n",
    "    fig, axes = plt.subplots(1, 3, figsize=(12, 4))\n",
    "\n",
    "    data = a\n",
    "    ax = axes[0]\n",
    "    ax.patch.set_facecolor('black')\n",
    "    ax.xaxis.set_major_locator(plt.NullLocator())\n",
    "    ax.yaxis.set_major_locator(plt.NullLocator())\n",
    "    colors = ['#1199ff', '#ee3311', '#66ff22']\n",
    "    for (m, n), w in np.ndenumerate(data):\n",
    "        size = 0.97\n",
    "        color = '#1199ff'\n",
    "        rect = plt.Rectangle([n - size / 2, m - size / 2],\n",
    "                             size, size,\n",
    "                             facecolor=color,\n",
    "                             edgecolor=color)\n",
    "        ax.add_patch(rect)\n",
    "        ax.text(m, n, \"%d\" % data[n, m], ha='center', va='center', fontsize=12)        \n",
    "    ax.text(2.8, 1, \"+\", ha='center', va='center', fontsize=22)        \n",
    "    ax.autoscale_view()\n",
    "    ax.invert_yaxis()\n",
    "    \n",
    "    data = np.zeros_like(a) + b\n",
    "    ax = axes[1]\n",
    "    ax.patch.set_facecolor('black')\n",
    "    ax.xaxis.set_major_locator(plt.NullLocator())\n",
    "    ax.yaxis.set_major_locator(plt.NullLocator())\n",
    "    colors = ['#1199ff', '#ee3311', '#66ff22']\n",
    "    for (m, n), w in np.ndenumerate(data):\n",
    "        size = 0.97\n",
    "        color = '#eeeeee'\n",
    "        rect = plt.Rectangle([n - size / 2, m - size / 2],\n",
    "                             size, size,\n",
    "                             facecolor=color,\n",
    "                             edgecolor=color)\n",
    "        ax.add_patch(rect)\n",
    "        if (np.argmax(b.T.shape) == 0 and m == 0) or (np.argmax(b.T.shape) == 1 and n == 0):\n",
    "            color = '#1199ff'\n",
    "            #size = 0.8\n",
    "            rect = plt.Rectangle([n - size / 2, m - size / 2],\n",
    "                                 size, size,\n",
    "                                 facecolor=color,\n",
    "                                 edgecolor=color)\n",
    "            ax.add_patch(rect)\n",
    "        ax.text(m, n, \"%d\" % data[n, m], ha='center', va='center', fontsize=12)        \n",
    "    ax.text(2.8, 1, \"=\", ha='center', va='center', fontsize=22)        \n",
    "    ax.autoscale_view()\n",
    "    ax.invert_yaxis()\n",
    "\n",
    "    \n",
    "    data = c\n",
    "    ax = axes[2]\n",
    "    ax.patch.set_facecolor('black')\n",
    "    ax.xaxis.set_major_locator(plt.NullLocator())\n",
    "    ax.yaxis.set_major_locator(plt.NullLocator())\n",
    "    colors = ['#1199ff', '#ee3311', '#66ff22']\n",
    "    for (m, n), w in np.ndenumerate(data):\n",
    "        size = 0.97\n",
    "        color = '#1199ff' if w > 0 else '#eeeeee'\n",
    "        color = '#eeeeee'\n",
    "        rect = plt.Rectangle([n - size / 2, m - size / 2],\n",
    "                             size, size,\n",
    "                             facecolor=color,\n",
    "                             edgecolor=color)\n",
    "        ax.add_patch(rect)\n",
    "        color = '#1199ff'\n",
    "        #size = 0.8\n",
    "        rect = plt.Rectangle([n - size / 2, m - size / 2],\n",
    "                             size, size,\n",
    "                             facecolor=color,\n",
    "                             edgecolor=color)\n",
    "        ax.add_patch(rect)\n",
    "        ax.text(m, n, \"%d\" % data[n, m], ha='center', va='center', fontsize=12)        \n",
    "    ax.autoscale_view()\n",
    "    ax.invert_yaxis()\n",
    "    \n",
    "    #fig.tight_layout()\n",
    "        \n",
    "    if filename:\n",
    "        fig.savefig(filename + \".png\", dpi=200)\n",
    "        fig.savefig(filename + \".svg\")\n",
    "        fig.savefig(filename + \".pdf\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "a = np.array([[11, 12, 13], [21, 22, 23], [31, 32, 33]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "b = np.array([[1, 2, 3]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "show_array_broadcasting(a, b, filename=\"array_broadcasting_1\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "show_array_broadcasting(a, b.T, filename=\"array_broadcasting_2\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Versions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "%reload_ext version_information"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "%version_information numpy, matplotlib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
